#include "lpc_2148.h"
#include "hardware.h"
#include "tn.h"
#include "type.h"
#include "utils.h"
#include "uart.h"
#include "74HC595.h"
#include "led.h"
#include "ps2kbd.h"
#include "test.h"
#include "lcd.h"
#include "usbapi.h"
#include "vcom.h"
#include "vga.h"

#define  TASK_HARDWARE_VERIFY_PRIORITY      4
#define  TASK_HARDWARE_VERIFY_STK_SIZE	    256
#define  TASK_TOM_PRIORITY                  6
#define  TASK_TOM_STK_SIZE                  256

extern void lpc2000_debug_devopen( int(*put)(int) );
extern void lpc2000_debug_printf(char const *format, ...);
extern void putch(int ch);
extern void putch1(int ch);
extern void start_step(void);
extern void change_step_delay(U8 ch);
extern void start_motor(void);
extern U8 Motor_Switch;     // s=stop g=go

U32 task_hardware_verify_stack[TASK_HARDWARE_VERIFY_STK_SIZE];
U32 task_tom_stack[TASK_TOM_STK_SIZE];

TN_TCB  tcb_hardware_verify_task;
TN_TCB  tcb_tom_task;

void hardware_verify_task(void *par);
void tom_task_func(void *par);

/**
*****************************************************************	
	Function Name :	main()

	Description :	To initialise system.

	Input :	none

	Output : int

	Note :
*****************************************************************
*/	
S32 main()
{
  unsigned int * ptr;
  tn_arm_disable_interrupts();
  MEMMAP = 0x1;    //-- FLASHs

  //------ Clear FW loader marks
  ptr =(unsigned int *)RAM_START_ADDR;
  *ptr = 0;
  ptr++;
  *ptr = 0;
  RSIR=0x0f;
  
  //------ Set interrupt vectors
  ptr = (unsigned int *)IRQ_RAM_ADDR;
  *ptr = 0xE59FF018;                      //-- ldr pc, [pc, #24]
  ptr = (unsigned int *)FIQ_RAM_ADDR;
  *ptr = 0xE59FF018;                      //-- ldr pc, [pc, #24]
  
  //--- Put IRQ & FIQ vectors in RAM
  ptr = (unsigned int *)IRQ_RAM_FUNC_ADDR;
  *ptr = (unsigned int)&tn_cpu_irq_isr;
  ptr = (unsigned int *)FIQ_RAM_FUNC_ADDR;
  *ptr = (unsigned int)&tn_cpu_fiq_isr;

  HardwareInit();

  lpc2000_debug_devopen(uart0Putch);
  lpc2000_debug_printf("app.c calling tn_start_system\n");

  tn_start_system(); //-- Never return

  return 1;
}

/**
********************************************************************************************
	Function Name :	tn_app_init()

	Description :	In this function there are two tasks ( task_main and task_led1) 
				created and activated.

	Input :	Void

	Output : Void

	Note :
**********************************************************************************************
*/
void  tn_app_init()
{
  //  message_queue_init();
  //  malloc_init();
  lpc2000_debug_printf("app.c enter tn_app_init\n");
//  delay(100000);
  tcb_hardware_verify_task.id_task = 0;
  tn_task_create(&tcb_hardware_verify_task,       //-- task TCB
                  hardware_verify_task,           //-- task function
                  TASK_HARDWARE_VERIFY_PRIORITY,  //-- task priority
                  &(task_hardware_verify_stack    //-- task stack first addr in memory
                  [TASK_HARDWARE_VERIFY_STK_SIZE-1]),
                  TASK_HARDWARE_VERIFY_STK_SIZE,  //-- task stack size (in int,not bytes)
                  NULL,                           //-- task function parameter
                  TN_TASK_START_ON_CREATION	//-- Creation option
                );

    //--- Tom's Test Task
    tn_task_create((TN_TCB*)&tcb_tom_task,         //-- task TCB
                 tom_task_func,                 //-- task function
                 TASK_TOM_PRIORITY,                                 //-- task priority
                 &(task_tom_stack           //-- task stack first addr in memory
                    [TASK_TOM_STK_SIZE-1]),
                 TASK_TOM_STK_SIZE,            //-- task stack size (in int,not bytes)
                 NULL,                              //-- task function parameter
                 TN_TASK_START_ON_CREATION        //-- Creation option
                 );


}

/**
********************************************************************************************
	Function Name :	hardware_verify_task()

	Description :
	
	Input :	Void

	Output : Void

	Note :
**********************************************************************************************
*/
void hardware_verify_task(void *par)
{
  U8 ch=0;
//  int a = 0;
//  delay(100000);
  //  for (int i; i<100000; i++) { a++; }
  lpc2000_debug_printf("app.c enter hardware_verify_task\n");
//  delay(100000);
//  for (int i; i<100000; i++) { a++; }

  if(is_usb_cable_connected())
  {
 //   while(!get_USB_enumeration_status());
  }
	
  test_leds();
  turn_off_all_leds();
  test_uart0();
  test_uart1();
  test_sd_card();
  test_i2c_at24c256_flash();
  if(get_USB_enumeration_status())
  {
    test_usb();
  }
  
  while(1)
  {
    if(keyhit())
    {
      process_lcd();
    }
    if ( uart0Receive(&ch, sizeof(ch)) != -1)
    {
      if (ch == 'r') 
      {
            putch(ch);
      }
      if (ch == 's') 
      {
            putch1(ch);
      }
      if (ch == 't') 
      {
            test_leds();
            turn_on_led(0x45);
      }

      if (ch == 'z')
      {
          lpc2000_debug_printf("got z, calling start_motor\n");
           start_motor();
      }
      if ((ch == '+') || (ch == '-'))
      {
           change_step_delay(ch);
      }

      test_my_uart0(ch);
//      test_uart0();
    }
//    uart1Putch('u');

    if ( uart1Receive(&ch,sizeof(ch)) != -1)
    {
      test_uart1();
    }

    if(get_USB_enumeration_status())
    {
      if(VCOM_read(sizeof(ch),&ch))
      {
        test_usb();
      }
    }
//    process_adc();
    tn_task_sleep(10);
  }
}

void tom_task_func(void *par)
{
       while(1)
       {
         //          lpc2000_debug_printf("Running tom_task_func\n");
         if (Motor_Switch == 'g')
           start_step();

          tn_task_sleep(1000);     // sleep for 1 sec
       }
}

